package IoPromptTestUtils;
use strict;
use warnings;

use base 'Exporter';
our @EXPORT;

our $HAVE_IO_PTY;
our $PTY_MASTER;
our $PTY_SLAVE;

our $TEST_COUNT_REF;
our @PROMPT_CHECK_HOOKS = ();
our @PROMPT_CHECK_CHAR_HOOKS = ();
our @INJECT_INPUT_HOOKS = ();
push @EXPORT, qw($HAVE_IO_PTY $PTY_MASTER $TEST_COUNT_REF);
push @EXPORT, qw(@PROMPT_CHECK_HOOKS @PROMPT_CHECK_CHAR_HOOKS @INJECT_INPUT_HOOKS);


BEGIN {
    eval 'use IO::Pty;';
    $HAVE_IO_PTY = !$@;
}

# Redefine IO::Prompt::_get_tty_fh_* to return a Pty
BEGIN {
    if ($HAVE_IO_PTY) {
        $PTY_MASTER = IO::Pty->new();
        $PTY_SLAVE = $PTY_MASTER->slave();

        # Fool IO::Prompt into thinking STDIN is attached to the PTY
        #print STDERR "Have fileno on STDIN before reopen: " . fileno(STDIN) . "\n";
        open STDIN, "<&", $IoPromptTestUtils::PTY_SLAVE;
        #print STDERR "Have fileno on STDIN after reopen: " . fileno(STDIN) . "\n";


        package IO::Prompt;
        no warnings 'redefine';

        sub _get_tty_fh_out { return $IoPromptTestUtils::PTY_SLAVE; }
        #sub _get_tty_fh_out { return \*STDOUT; }
        sub _get_tty_fh_in { return $IoPromptTestUtils::PTY_MASTER; }

        use warnings 'redefine';
        package IoPromptTestUtils;
    }
}


# Override _tester* subs to call each registered hook
#push @EXPORT qw(@PROMPT_CHECK_HOOKS @PROMPT_CHECK_CHAR_HOOKS @INJECT_INPUT_HOOKS);

BEGIN {
    package IO::Prompt;
    no warnings 'redefine';

    sub _testing_inject_input {
        foreach my $hook (@IoPromptTestUtils::INJECT_INPUT_HOOKS) {
            $hook->($IoPromptTestUtils::TEST_COUNT_REF, @_);
        }
    }

    sub _testing_check_prompt_output {
        my ($OUT) = @_;
        $OUT->flush();
        foreach my $hook (@IoPromptTestUtils::PROMPT_CHECK_HOOKS) {
            $hook->($IoPromptTestUtils::TEST_COUNT_REF, $OUT);
        }
    }

    sub _testing_check_prompt_output_char {
        my ($OUT) = @_;
        $OUT->flush();
        foreach my $hook (@IoPromptTestUtils::PROMPT_CHECK_CHAR_HOOKS) {
            $hook->($IoPromptTestUtils::TEST_COUNT_REF, $OUT);
        }
    }

    use warnings 'redefine';
    package IoPromptTestUtils;
}



1;
